home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigantic Games 2
/
Gigantic Games 2.iso
/
pc
/
_m_
/
minesweeper
/
field.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-23
|
5KB
|
197 lines
// This may look like C code, but it is really -*- C++ -*-
///////////////////////////////////////////////////////////////////////////
//
// AMIGA Minesweeper - Definition of the Field-object
//
// (c) 1992 Hubert Feyrer (c9020@rrzc1.rz.uni-regensburg.de)
//
///////////////////////////////////////////////////////////////////////////
#define class _class
#define IntuitionBase IntuiBase
#define GfxBase GraphBase
extern "C" {
# include <stdio.h>
# include <exec/types.h>
# include <utility/tagitem.h>
# include <intuition/gadgetclass.h>
# include <libraries/gadtools.h>
# include <clib/gadtools_protos.h>
# include <clib/intuition_protos.h>
# include <clib/graphics_protos.h>
# include <ctype.h>
}
#define IntuitionBase IntuitionBase
#define GfxBase GfxBase
#define class class
#include "mine.h"
#include "field.h"
Gadget *Field::lastgad=NULL; // Wird in main() auf Ergebnis
// von CreateContext() gesetzt!
//
// Klassendefinition für ein Feld des Mine-Programmes
//
Field::Field(int x, int y, int i, int j){
static struct NewGadget ngad={
-1,-1,-1,-1, /* x, y, w, h */
NULL, /* ng_GadgetText */
NULL, /* font */
0, /* gadget-id */
PLACETEXT_IN, /* flags */
NULL, /* von GetVisualInfo() */
NULL /* userdata */
};
ngad.ng_VisualInfo = vinfo;
ngad.ng_TextAttr = scr->Font;
(ngad.ng_GadgetText = strcpy(txt," "))[0]=BLANK;
ngad.ng_LeftEdge = x;
ngad.ng_TopEdge = y;
ngad.ng_Width = fxs;
ngad.ng_Height = fys;
lastgad=_gad=CreateGadget(BUTTON_KIND,lastgad,&ngad,TAG_END);
if(_gad==NULL){
fprintf(stderr,"Field::Field(%d,%d): Fehler in "
"CreateGadget()!\n",x,y);
shutdown(20);
}
_gad->Flags &= ~GFLG_SELECTED;
_gad->UserData = (APTR)this;
_cnt=0; // Anzahl Nachbarminen; später!
_open=0; // nicht aufgedeckt
_i=i; // Spalte im minefield[][]
_j=j; // Zeile im minefield[][]
countdown++; // 1 Feld mehr zu erforschen
}
Field::~Field(void)
{
// Nichts zu tun???
}
//*
//* Feld in Ausgangszustand versetzen
//*
void Field::clear(void)
{
_open=0;
_gad->Flags &= ~GFLG_SELECTED;
_cnt=0;
txt[0]=BLANK;
}
//*
//* Feld aufdecken
//*
void Field::open(int show=0)
{
if(!_open){
long pos = RemoveGadget(win,_gad);
_open=1;
if(show){
if(_cnt==-1){
_gad->Flags &= ~GFLG_SELECTED;
txt[0]=BOMB;
}else{
_gad->Flags |= GFLG_SELECTED;
if(!isdigit(txt[0])) txt[0]=BLANK;
}
}else{
_gad->Flags |= GFLG_SELECTED;
switch(_cnt){
case -1:
txt[0] = BOMB;
break;
case 0:
txt[0] = BLANK;
break;
default:
txt[0] = NUM+_cnt;
}
}
AddGadget(win,_gad,pos);
RefreshGList(_gad,win,NULL,1);
}
}
//*
//* Feld überprüfen; force==1: auch markierte Felder
//*
GameStat Field::check(int force=0)
{
if(txt[0]==BLANK || force){
if(!_open){
if(_cnt==-1) return GAME_LOST; // BUMM!
if(force && txt[0]==MARK && _cnt!=-1) minesleft++;
open();
if(_cnt==0){
// rekursives check()en...
for(int v=0;v<8;v++){
int vi=_i+validfields[v].dx;
int vj=_j+validfields[v].dy;
if(inminefield(vi,vj)){
Field *m=minefield[vi][vj];
if(m->cnt()!=-1 && !m->_open){
// *** Rekursion *** //
minefield[vi][vj]->check(1);
sprintf(tnumgad,"%04d",minesleft);
if(tnumgad[0]=='0') tnumgad[0]=' ';
GT_SetGadgetAttrs(numgad,win,NULL,
GTTX_Text,tnumgad,
TAG_END);
}
}
}
}
countdown--; // 1 Feld weniger zum Sieg
if(countdown==0) return GAME_WON;
}
}
return GAME_CONT;
}
GameStat Field::mark(void)
{
if(!_open){
char *t=txt;
// Markierung setzen/löschen
long pos = RemoveGadget(win,_gad);
*t = (*t==BLANK)?MARK:BLANK;
AddGadget(win,_gad,pos);
RefreshGList(_gad,win,NULL,1);
minesleft+=(*t==MARK)?-1:1;
sprintf(tnumgad,"%04d",minesleft);
if(tnumgad[0]=='0') tnumgad[0]=' ';
GT_SetGadgetAttrs(numgad,win,NULL,
GTTX_Text,tnumgad,
TAG_END);
RefreshGList(numgad,win,NULL,1);
if(_cnt==-1){
if(*t==MARK)
countdown--; // 1 Feld weniger zum Sieg...
else
countdown++; // ...oder mehr!
if(countdown==0) return GAME_WON;
}
}
return GAME_CONT;
}